package com.cn.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cn.entity.Finally;
import com.cn.entity.FinallyOne;
import com.cn.utlis.CreateSqlUtils;
import com.cn.utlis.IBase;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.Table;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.cn.utlis.CreateSqlUtils.setSQLValues;

/**
 * Created by chenyuncong on 2019/5/10.
 */
@Service("finallyService")
@Slf4j
public class FinallyServiceImpl extends IBase<Finally> implements FinallyService {

    @Resource
    private FinallyOneService finallyOneService;

    public void createSqlBatch(String path) {
        File file = new File(path);
        BufferedReader br = null;
        if (file.exists()) {
            try {
                br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
                String s = null;
                JSONObject boj = null;
                Map<String, Object> o = null;
                List<Finally> list = new ArrayList<>(670000);
                Finally f = null;
                FinallyOne fo = null;
                String psthName="D:\\file\\sql\\";
                int i = 0;
                long startTime = System.currentTimeMillis();
                while ((s = br.readLine()) != null) {  //使用readLine方法，一次读一行
                    boj = JSONObject.parseObject(s);
                    o = (Map<String, Object>) boj.get("_source");
                    if (o.containsKey("house_quantity")) {
                        try {
                            f = get(o);
                            if (f == null) {
                                continue;
                            }
                            if (checkFinally(f)) {
                                list.add(f);
                                i++;
                                if (i % 500000 == 0) {
//                                    this.saveBatch(list);
                                    writeFile(psthName+System.currentTimeMillis()+"-"+i+".sql",list);
                                    log.info("num:[{}] size:[{}] time:[{}] ", i, list.size(), (System.currentTimeMillis() - startTime));
                                    list.clear();
                                    startTime = System.currentTimeMillis();
                                }
                            } else {
//                                fo = new FinallyOne();
//                                BeanUtils.copyProperties(f, fo);
//                                finallyOneService.save(fo);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
                writeFile(psthName+System.currentTimeMillis()+"-"+i+".sql",list);
            } catch (Exception e) {
            }
        }
    }

    private static void writeFile(String path, List<Finally> list) {
        File writeName = new File(path); // 相对路径，如果没有则要建立一个新的output.txt文件
        FileWriter writer = null;
        BufferedWriter out = null;
        try {
            //"D:\\testData\\output.txt"
            writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
            writer = new FileWriter(writeName);
            out = new BufferedWriter(writer);
            int i = 0;
//            StringBuffer sql = new StringBuffer(getInsertSQL(list.get(0)));
            StringBuffer sql = new StringBuffer();
            for (Finally c : list) {
//                if(i!=0){
//                    sql.append(",");
//                }
//                setSQLValues(c,sql);
//                if (i == 100) {
//                    sql.append(";");
//                    out.write(sql.toString() + "\r\n"); // \r\n即为换行
//                    out.flush();
//                    i = 0;
//                    sql = new StringBuffer(getInsertSQL(list.get(0)));
//                }
                sql.append(CreateSqlUtils.getInsertSQL(list.get(0)));
                CreateSqlUtils.setSQLValues(c,sql);
                sql.append(";\r\n");
                if (i == 100) {
                    out.write(sql.toString()); // \r\n即为换行
                    out.flush();
                    i = 0;
                    sql = new StringBuffer();
                }
                i++;
            }
//            sql.append(";");
            out.write(sql.toString() + "\r\n"); // \r\n即为换行
            out.flush(); // 把缓存区内容压入文件
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null)
                    out.close();
                if (writer != null)
                    writer.close();
            } catch (Exception e) {
            }
        }
    }

//    public static void setSQLValues(Object f,StringBuffer sb) throws Exception {
//        sb.append("(");
//        String fieldName=null;
//        String methodName=null;
//        Method method=null;
//        Object resultValue=null;
//        for (Field field : f.getClass().getDeclaredFields()) {
//            field.setAccessible(true);
//            fieldName = field.getName();
//            if(fieldName.equals("id")){
//                continue;
//            }
//            methodName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
//            method = f.getClass().getMethod(methodName, new Class[]{});
//            resultValue = method.invoke(f, new Object[]{});
//            if (resultValue instanceof Integer){
//                sb.append(resultValue).append(",");
//            }else if(resultValue instanceof String){
//                if(resultValue.equals("'")){
//                    sb.append("'").append(((String) resultValue).replaceAll("'","")).append("',");
//                }else{
//                    sb.append("'").append(resultValue).append("',");
//                }
//            }else{
//                sb.append("NULL").append(",");
//            }
//        }
//        if(sb.length()>0){
//            sb.deleteCharAt(sb.length()-1);
//        }
//        sb.append(")");
//    }

//    public static String getInsertSQL(Object f) throws Exception {
//        String name;
//        StringBuffer sb = new StringBuffer("insert into ");
//        Table table = f.getClass().getAnnotation(Table.class);
//        String tableName = table.name();
//        sb.append(tableName).append("(");
//
//        for (Field field : f.getClass().getDeclaredFields()) {
//            field.setAccessible(true);
//            name = field.getName();
//            if (!name.equals("id")) {
//                sb.append(name).append(",");
//            }
//        }
//        if(sb.length()>0){
//            sb.deleteCharAt(sb.length()-1);
//        }
//        sb.append(") values ");
//        return sb.toString();
//    }


    public void reData(String path) {

//        String path = "C:\\file2\\alg-customer-finally.json";
        File file = new File(path);
        BufferedReader br = null;
        if (file.exists()) {
            try {
                br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
                String s = null;
                JSONObject boj = null;
                Map<String, Object> o = null;
                List<Finally> list = new ArrayList<>(1500);
                Finally f = null;
                FinallyOne fo = null;
                int i = 0;
                int index = 0;
                int sign = 12072467;
                long startTime = System.currentTimeMillis();
                while ((s = br.readLine()) != null) {  //使用readLine方法，一次读一行
                    index++;
                    if (index < sign) {
                        continue;
                    }
                    boj = JSONObject.parseObject(s);
                    o = (Map<String, Object>) boj.get("_source");
                    if (o.containsKey("house_quantity")) {
                        try {
                            f = get(o);
                            if (checkFinally(f)) {
                                list.add(f);
                                i++;
                                if (i % 1000 == 0) {
                                    this.saveBatch(list);
                                    log.info("num:[{}] size:[{}] time:[{}] index:[{}]", i, list.size(), (System.currentTimeMillis() - startTime), index);
                                    list.clear();
                                    startTime = System.currentTimeMillis();
                                }
                            } else {
                                fo = new FinallyOne();
                                BeanUtils.copyProperties(f, fo);
                                finallyOneService.save(fo);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
                this.saveBatch(list);

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (br != null) {
                        br.close();
                    }

                } catch (IOException e1) {
                }
            }
        }

    }

    public Finally get(Map<String, Object> obj) {
        Finally f = new Finally();
        Value v = null;
        Object o=null;
        try {
            for (Field field : f.getClass().getDeclaredFields()) {
                if (obj.containsKey(field.getName())) {
                    if (!field.getName().equals("relevance_phone_no")) {
                        field.setAccessible(true);
                        try {
                            if (field.getName().equals("property_places")) {
                                int s = obj.get(field.getName()) == null ? 0 : obj.get(field.getName()).toString().length();
                                if (s >= 400) {
                                    field.set(f, obj.get(field.getName()).toString().substring(0, 401));
                                } else {
                                    field.set(f, obj.get(field.getName()));
                                }
                            } else {
                                if (field.getName().equals("credit_level")||field.getName().equals("purchasing_power")||field.getName().equals("accord_with_area")) {
                                    field.set(f, obj.get(field.getName()) == null ? null : Integer.parseInt(obj.get(field.getName()).toString()));
                                }else if(field.getName().equals("house_type")){
                                    //get_hall_number
                                    o=obj.get(field.getName());
                                    if(o == null){
                                        field.set(f, null);
                                    }else{
                                        field.set(f, o.toString().indexOf("get_hall_number")>0?o.toString().substring(0,o.toString().indexOf("get_hall_number")):o);
                                    }
                                } else {
                                    field.set(f, obj.get(field.getName()));
                                }

                            }

                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } catch (Exception e) {
            return null;
        }
        return f;
    }

    public static boolean checkFinally(Finally f) throws IllegalAccessException {
        //             phone_no;// 12
        Object obj;
        String name;
        int length;
        for (Field field : f.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            obj = field.get(f);
            if (obj != null) {
                length = (obj == null ? 0 : obj.toString().length());
                name = field.getName();
                if (finallyPatam.containsKey(name)) {
                    if (finallyPatam.get(name) < length) {
                        log.info("name:[{}] length:[{}]", name, length);
                        return false;
                    }
                }
            }
        }
        return true;
    }

    static Map<String, Integer> finallyPatam = new HashMap<String, Integer>() {{
//         private String phone_no;// 12
//         private String contract_hukou; //50
//         private Integer credit_level;//1 int
//         private String gender; // 2 性别
//         private String hard_contact; //4
        put("phone_no", 12); //户口地址
        put("contract_hukou", 50); //户口地址
        put("credit_level", 1);
        put("gender", 2); //性别
        put("hard_contact", 4);
//         private String house_quota; //5
//         private String easy_contact; // 3
//         private String active_customer; //4
//         private String investment; //4
        put("house_quota", 5);
        put("easy_contact", 4);
        put("active_customer", 4);
        put("investment", 4);
//         private String business_trip; //4 长期出差
//         private String inactive_customer; //4 非活跃客
//         private String recent_seen_property;// 50 最近看过的房源
//         private String ask_area;  //20 地区需求
        put("business_trip", 4);//长期出差
        put("inactive_customer", 4);//非活跃客
        put("recent_seen_property", 50);//最近看过的房源
        put("ask_area", 20);//地区需求
//             direction; //35 朝向
//             active_area; //50 做逗号分隔 截取
//             marital_status; // 10 婚姻状态
//             property_type; //50 物业意向
        put("direction", 35);
        put("active_area", 50);
        put("marital_status", 10);
        put("property_type", 50);
//             house_type; // 50 户型
//             must_need; //3 刚需情况
//             loan_status; //3 贷款情况
//             gjj; //6 公积金
        put("house_type", 50);
        put("must_need", 4);
        put("loan_status", 4);
        put("gjj", 6);
//             high_income_families; //6 家庭收入情况
//             buy_range; //30 价格范围
//             rent_range; //20 租金范围
//             square_range; //20 需求房产面积
        put("high_income_families", 6);
        put("buy_range", 30);
        put("rent_range", 20);
        put("square_range", 20);
//             purchasing_power; // 1 int
//             house; //4 有房一族 标签
//             property_grade; //20 拥有物业估价
//             property_places;//50 拥有房产
        put("purchasing_power", 1);
        put("house", 4);
        put("property_grade", 20);
        put("property_places", 50);
//             car;//4 有车一族
//             house_quantity;// 10 拥有房产数量
//             children;//3 有小孩
//             accord_with_area;//1 int
        put("car", 4);
        put("house_quantity", 10);
        put("children", 4);
        put("accord_with_area", 1);
//             loan_type; //8 贷款买房 或 最近有申请房贷
//             loan_amount; //20 贷款金额
//             loan_year;//12 贷款年限
        put("loan_type", 8);
        put("loan_amount", 20);
        put("loan_year", 12);

    }};

    public static void main(String[] args) throws Exception {
        Finally f= new Finally();
        f.setContract_hukou("aaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaa");
//        System.out.println(checkFinally(f));
//
//        FinallyOne fo=new FinallyOne();
//        BeanUtils.copyProperties(f,fo);
//
//        System.out.println(fo);

//        System.out.println(finallyPatam.hashCode());
//        System.out.println(finallyPatam.hashCode());
//        System.out.println(finallyPatam.hashCode());
//        System.out.println(finallyPatam.hashCode());
        StringBuffer sb = new StringBuffer(CreateSqlUtils.getInsertSQL(f));
        System.out.println(sb.toString());
        setSQLValues(f,sb);
        System.out.println(sb.toString());
        sb.append(",");
        setSQLValues(f,sb);
        System.out.println(sb.toString());
    }
}
